﻿using UnityEngine;
using Message;
using System.Collections.Generic;
using System.Timers;

/// <summary>
/// 玩家移动控制
/// </summary>
public class PlayerMoveControl : MonoBehaviour
{
    /// <summary>
    /// 摇杆
    /// </summary>
    public Joystick joystick;
    /// <summary>
    /// 旋转角度
    /// </summary>
    private float angle;
    /// <summary>
    /// 是否在玩家控制中
    /// </summary>
    private bool isCtrl = true;

    Vector3 vecMove;
    /// <summary>
    /// 位置
    /// </summary>
    Vector3 pos;
    /// <summary>
    /// 旋转
    /// </summary>
    Quaternion qu;

    /// <summary>
    /// 移动速度
    /// </summary>
    public float moveSpeed = 50;

    /// <summary>
    /// 位置同步200毫秒一次
    /// </summary>
    public static float posRate = 200;
    /// <summary>
    /// 定时器
    /// </summary>
    Timer timer = new Timer(posRate);

    /// <summary>
    /// 本地玩家字典
    /// </summary>
    public Dictionary<int, Player> playerDic = new Dictionary<int, Player>();
    /// <summary>
    /// 当前的位置信息
    /// </summary>
    public Dictionary<int, Trans> oldTrans = new Dictionary<int, Trans>();
    /// <summary>
    /// 新的位置信息
    /// </summary>
    public Dictionary<int, Trans> newTrans = new Dictionary<int, Trans>();

    /// <summary>
    /// 服务器发过来的玩家uid集合
    /// </summary>
    public List<int> netPlayerUids = new List<int>();

    /// <summary>
    /// 本地玩家集合
    /// </summary>
    public List<Player> players = new List<Player>();

    void Start()
    {
        //注册周围玩家的位置信息
        MsgMgr.Instance.AddListener(typeof(S2CMoves), OnOtherMoves);
        timer.Elapsed += new ElapsedEventHandler(HandleMainTimer);
        timer.AutoReset = false;
        timer.Enabled = true;
    }

    // Update is called once per frame
    void Update()
    {
        if (joystick != null && isCtrl)
        {
            vecMove = new Vector3(joystick.Direction.x, 0, joystick.Direction.y) * Time.deltaTime * moveSpeed / 10;
            transform.localPosition += vecMove;
            angle = Mathf.Atan2(joystick.Direction.x, joystick.Direction.y) * Mathf.Rad2Deg - 10;
            transform.localRotation = Quaternion.Euler(Vector3.up * angle);
            pos = transform.position;
            qu = transform.rotation;
        }
    }

    bool isLerping = false;
    float lerpTimeLength = 0.2f;
    float timeStartedLerping;
    void FixedUpdate()
    {
        if (isLerping)
        {
            float timeSinceStarted = Time.time - timeStartedLerping;
            float percentageComplete = timeSinceStarted / lerpTimeLength;
            foreach (int uid in newTrans.Keys)
            {
                playerDic[uid].SetPosition(Vector3.Lerp(new Vector3(oldTrans[uid]._x, oldTrans[uid]._y, oldTrans[uid]._z),
                  new Vector3(newTrans[uid]._x, newTrans[uid]._y, newTrans[uid]._z), percentageComplete));
                Quaternion q1 = new Quaternion();
                q1.eulerAngles = new Vector3(0, oldTrans[uid]._angle, 0);
                Quaternion q2 = new Quaternion();
                q2.eulerAngles = new Vector3(0, newTrans[uid]._angle, 0);

                playerDic[uid].SetRotation(Quaternion.Lerp(q1, q2, percentageComplete));
            }
            if (percentageComplete >= 1.0f)
            {
                isLerping = false;
            }
        }
    }

    private void HandleMainTimer(object sender, ElapsedEventArgs e)
    {
        SendMove();
        timer.Start();
    }

    /// <summary>
    /// 向服务器发送位置旋转信息
    /// </summary>
    void SendMove()
    {
        C2SMove ctsm = new C2SMove();
        ctsm.uid = GlobeData.uid;
        ctsm.x = pos.x;
        ctsm.y = pos.y;
        ctsm.z = pos.z;
        ctsm.angle = qu.eulerAngles.y;
        NetMgr.Instance.Send(ctsm);
    }

    /// <summary>
    /// 更新其他人的位置信息
    /// </summary>
    /// <param name="data"></param>
    void OnOtherMoves(object data)
    {
        //更新位置信息
        S2CMoves stcm = data as S2CMoves;
        netPlayerUids.Clear();
        oldTrans.Clear();
        newTrans.Clear();

        //Log.Debug(stcm.moves.Count);  
        for (int i = 0; i < stcm.moves.Count; i++)
        {
            C2SMove ctsm = stcm.moves[i];
            netPlayerUids.Add(ctsm.uid);

            if (ctsm.uid != GlobeData.uid)
            {
                if (playerDic.ContainsKey(ctsm.uid))
                {
                    Trans t1 = playerDic[ctsm.uid].GetTrans();
                    oldTrans.Add(ctsm.uid, t1);
                    Trans t2 = new Trans(ctsm.x, ctsm.y, ctsm.z, ctsm.angle);
                    newTrans.Add(ctsm.uid, t2);
                }
                else
                {
                    Log.Debug("here");
                    ResMgr.Instance.Load("player", delegate (GameObject gameObject)
                    {
                        //添加其他玩家模型
                        Player player = gameObject.AddComponent<Player>();
                        player.uid = ctsm.uid;
                        player.name = ctsm.uid.ToString();
                        player.transform.Find("Text").GetComponent<TextMesh>().text = ctsm.uname;
                        //设置位置信息
                        player.SetPosition(new Vector3(ctsm.x, ctsm.y, ctsm.z));
                        Quaternion q = new Quaternion();
                        q.eulerAngles = new Vector3(0, ctsm.angle, 0);
                        player.SetRotation(q);
                        playerDic.Add(ctsm.uid, player);
                        players.Add(player);
                    });
                }
            }
        }

        for (int i = 0; i < players.Count; i++)
        {
            Player player = players[i];
            int uid = player.uid;
            if (!netPlayerUids.Contains(player.uid))
            {
                players.Remove(player);
                Destroy(player.gameObject);
                playerDic.Remove(uid);
            }
        }

        isLerping = true;
        timeStartedLerping = Time.time;
    }

    private void OnApplicationQuit()
    {
        timer.Stop();
    }
}

public class Trans
{
    public float _x;
    public float _y;
    public float _z;
    public float _angle;

    public Trans(float x, float y, float z, float angle)
    {
        _x = x;
        _y = y;
        _z = z;
        _angle = angle;
    }
}